package com.systop.common.modules.template.freemarker;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import org.springframework.ui.freemarker.FreeMarkerConfigurationFactory;

import freemarker.template.Configuration;
import freemarker.template.TemplateException;

/**
 * <code>FreeMarkerConfigurationManager</code>继承了
 * {@link FreeMarkerConfigurationFactory},使之可以添加新的
 * @author Sam Lee
 * 
 */
@SuppressWarnings({"unchecked", "rawtypes"})
public class FreeMarkerConfigurationManager extends
    FreeMarkerConfigurationFactory {
  /**
   * 用于保存Tamplate文件的路径.
   */
  private Set paths = new HashSet();

  /**
   * 用于标识是否添加了新的templateLoaderPath
   */
  private boolean pathChanged = false;

  /**
   * instance of freemarker Configuration.因为FreeMarkerConfigurationManager
   * 是由spring管理的bean，所以configuration是符合spring bean的生命周期的。在
   * FreeMarkerConfigurationManager中，
   * 如果pathChanged=true,configuration会重新 创建.
   */
  private Configuration configuration;

  /**
   * @see FreeMarkerConfigurationFactory#createConfiguration()
   */
  @Override
  public Configuration createConfiguration() throws IOException,
      TemplateException {
    try {
      if (configuration == null || pathChanged) {
        this.setTemplateLoaderPaths(null); // 重新设置Loader path
        configuration = super.createConfiguration();
        logger.info("Create new freemarker Configuration");
      } else {
        logger.info("Use existed Configuration");
      }
    } catch (FileNotFoundException e) {
      logger.warn("模板目录不存在:" + e.getMessage());
    }

    return configuration;
  }

  /**
   * @see FreeMarkerConfigurationFactory#setTemplateLoaderPath(String)
   */
  @Override
  public void setTemplateLoaderPath(String templateLoaderPath) {
    // 如果新设置的templateLoaderPath变量包含新的位置，则加入paths中
    // 并重新设置标识变量pathChanged为true
    if (!paths.contains(templateLoaderPath)) {
      paths.add(templateLoaderPath);
      pathChanged = true;
      logger.info("Add new path [" + templateLoaderPath + "]");
    }
  }

  /**
   * @see FreeMarkerConfigurationFactory#setTemplateLoaderPaths(String[])
   */
  @Override
  public void setTemplateLoaderPaths(String[] templateLoaderPaths) {
    // 调用setTemplateLoaderPath(String)方法，循环加入.
    if (templateLoaderPaths != null) {
      for (int i = 0; i < templateLoaderPaths.length; i++) {
        setTemplateLoaderPath(templateLoaderPaths[i]);
      }
    }
    // 如果有新的templateLoaderPath变量，则重新设置
    if (pathChanged) {
      String[] loaderPaths = (String[]) paths.toArray(new String[] {});
      if (loaderPaths != null) {
        logger.info("Reset templateLoader paths, size is ["
            + loaderPaths.length + "]");
        super.setTemplateLoaderPaths(loaderPaths);
      }
    }
  }

}
